package com.ng.common.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.ng.common.constants.SecurityConstants;
import com.ng.common.exception.ExpiredTokenException;
import com.ng.common.util.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
//@RequiredArgsConstructor
@Aspect
@Component
@Slf4j
public class JwtAuthRequiredAop {

	@Autowired
	private JwtUtil jwtUtil;

	@Pointcut("@annotation(com.ng.common.annotation.TokenRequired)")
	private void pointcut() {
	}

	@Around("pointcut()")
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		assert attributes != null;
		HttpServletRequest request = attributes.getRequest();
		String authorizationHeader = request.getHeader("Authorization");
		if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
			try {
				String token = authorizationHeader.substring(7);
				String username = jwtUtil.extractUsername(token);
				if (username != null && jwtUtil.validateToken(token, username)) {
					try {
						Claims claims = jwtUtil.extractAllClaims(token);
						if (claims != null) {
							request.setAttribute(SecurityConstants.CUR_USER_ID, claims.get("id"));
							request.setAttribute(SecurityConstants.CUR_USER_NAME, claims.get("deptId"));
							request.setAttribute(SecurityConstants.CUR_USER_DEPT_ID, claims.get("username"));
						}
					} catch (Exception e) {
						throw e;
					}
					return joinPoint.proceed();
				}
			} catch (Exception e) {
				throw e;
			}
		}
		throw new ExpiredTokenException("Unauthorized.");
	}
}
